#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "sdkconfig.h"
#include "driver/rmt.h"
#include "nvs_flash.h"
#include "esp_system.h"

#include "RCS_protocol.h"
#include "RCS_system.h"
#include "RCS_btn.h"
#include "RCS_fire.h"
#include "RCS_ble_master.h"
#include "RCS_led.h"
#include "RCS_adc.h"
/////////////////////GLOBAL VARIABLE/////////////////////
extern rcs_station_system_t rcsSystem;

QueueHandle_t xGameQueue;
TaskHandle_t shockTaskHandle;
TaskHandle_t bleserverTaskHandle;

static const char *TAG = "SYS";
static const char *SHOCK_TAG = "SHOCK";
static const char *LED_TAG = "LED";
static const char *BLE_TAG = "BLE";
static const char *IR_TAG = "IR";
static const char *GAME_TAG = "GAME";

/////////////////////TASK DECLAIRATION/////////////////////
static void game_task(void *arg);
static void ble_server_task(void *arg);
static void led_task(void *arg);

void app_main(void)
{
  /* Initialize NVS. */
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }

  // 保持供电
  power_init();
  ESP_LOGI(TAG, "..........power_init............");

  // 创建消息队列
  xGameQueue = xQueueCreate(10, ARMOR_UPL_PACK_MAX_LEN);

  // 创建事件组，连接成功事件，被击中事件，收到遥控器命令事件
  game_event_init();
  // 电量查询初始化
  rcs_adc1_init();
  // 恢复系统信息
  remember_sys_state();

  // 按钮初始化
  btn_init();
  // freertos任务优先级是数字越高越优先
  // 蓝牙任务:
  xTaskCreate(ble_server_task, "ble_server_task", 1024 * 15, NULL, 7, &bleserverTaskHandle);

  // 红外任务：
  xTaskCreate(rcs_ir_rx_task, "ir_rx_task", 1024 * 10, NULL, 8, NULL);

  // 灯光任务：
  xTaskCreate(led_task, "led_task", 1024 * 3, NULL, 4, NULL);

  // 数据处理任务：
  xTaskCreate(game_task, "game_task", 1024 * 5, NULL, 10, NULL);

  ESP_ERROR_CHECK(ret);
  ESP_LOGI(TAG, "[APP] Startup..");
  ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
  ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
}

/**
 * @brief: 初始化蓝牙，开启底层的蓝牙FSM(有限状态机)，
 *  开启不同名字的广播
 *  等待游戏开始：
 *  没有手机连上时，先开启手机名字。
 *  c3-ble
 *  adding状态：
 *  adding
 *  游戏中
 *  判断
 *
 * @param  {*}
 * @return {*}
 * @Author: TzzzT
 * @Date: 2022-04-20 00:45:02
 * @LastEditTime: Do not edit
 * @LastEditors: Shadow
 * @param {void} *arg
 */
static void ble_server_task(void *arg)
{
  remember_ble_setting();
  ESP_LOGI(BLE_TAG, "station ble_server_task Startup..");
  // ESP_LOGE(BLE_TAG, "rcsSystem.device.state: %s.",state_name(rcsSystem.device.state));
  rcs_start_advertise(rcsSystem.station_type);
  while (1)
  {
    rcs_stop_advertise();
    ESP_LOGI(BLE_TAG, "station_type: %d", rcsSystem.station_type);
    rcs_start_advertise(rcsSystem.station_type);
    vTaskSuspend(NULL);
    // ESP_LOGI(BLE_TAG, "running");
    // vTaskDelay(pdMS_TO_TICKS(5000));
  }
}

#define EVENT_INTERVAL 100

static void led_task(void *arg)
{
  rcs_event_t *event;
  uint8_t game_no_start_count = 0;
  uint8_t low_battery_count = 0;
  led_t led_2 = {
      .state = true,
      .delay_time = 1000};
  led_init();
  ESP_LOGI(LED_TAG, "led_task Startup..");
  while (1)
  {
    // 先判断有没有事件，如果有先执行事件的显示，没有事件再根据状态显示，只会有一种事件
    event = get_game_event_state();
    if (event->class)
    {
      led_2.state = (event->count % 2 == 0) ? true : false;
      led_2.delay_time = EVENT_INTERVAL;
      update_game_event();
    }
    else
    {
      if (rcsSystem.game.start)
      {
        // 游戏开始
        if (rcsSystem.game.player.living)
        {
          // 活着
          // led_2.state = (rcsSystem.game.player.team % 2 == 1) ? true : false;
          led_2.state = false;
        }
        else
        {
          // 死亡
          led_2.state = !led_2.state;
          led_2.delay_time = 500;
        }
      }
      else
      {
        // 游戏未开始
        if (rcsSystem.equip.core.battery < LOW_BATTERY)
        {
          // 低电量警告
          if (low_battery_count >= 50)
          {
            low_battery_count = 0;
          }
          if (low_battery_count < 2)
          {
            led_2.state = true;
          }
          else
          {
            led_2.state = false;
          }
          led_2.delay_time = 100;
          low_battery_count++;
        }
        else
        {
          // 普通情况
          if (game_no_start_count >= 20)
          {
            game_no_start_count = 0;
          }
          led_2.state = (game_no_start_count < 10) ? true : false;
          led_2.delay_time = 100;
          game_no_start_count++;
        }
      }
    }
    set_led_val(LED_2_PIN, led_2.state);
    vTaskDelay(pdMS_TO_TICKS(led_2.delay_time));
  }
}

static void game_task(void *arg)
{
  uint8_t package[ARMOR_UPL_PACK_MAX_LEN];
  BaseType_t xStatus;
  game_setting_init();
  ESP_LOGE(GAME_TAG, "game_task Startup..");
  while (1)
  {
    xStatus = xQueueReceive(xGameQueue, package, portMAX_DELAY);
    if (xStatus == pdPASS)
    {
      ESP_LOGE(GAME_TAG, "get queue");
      game_package_handle(package);
    }
  }
}
